/*
 * BinaryStreamReader.cpp
 *
 *  Created on: Mar 20, 2014
 *      Author: knuke
 */

#include "BinaryStreamReader.hpp"
#include "ImporterException.hpp"
#include <fstream>
#include <string>
#include <vector>
#include "Types.hpp"

using std::ifstream;
using std::ios;
using std::string;
using std::vector;

namespace gengine
{
  BinaryStreamReader::BinaryStreamReader() :
      pos_(0)
  {

  }

  BinaryStreamReader::BinaryStreamReader(string file_name) :
      pos_(0)
  {
    fromFile(file_name);
  }

  BinaryStreamReader::~BinaryStreamReader() throw ()
  {

  }

  void BinaryStreamReader::fromFile(string file_name)
  {
    pos_ = 0;
    ifstream file(file_name.c_str(), ios::in | ios::binary);
    if (!file.is_open())
      throw ImporterException("Cannot open file '" + file_name + "'.");

    file.seekg(0, ios::end);
    int file_size = file.tellg();
    file.seekg(0, ios::beg);

    data_ = vector<uchar>(file_size);
    file.read((char*) &data_[0], file_size);
    file.close();
  }

  int BinaryStreamReader::nextInt(short bytes)
  {
    int result = 0;
    for (uint pos = pos_; pos < pos_ + bytes; pos++)
    {
      result <<= 8;
      result += data_[pos];
    }
    pos_ += bytes;
    return result;
  }

  vector<int> BinaryStreamReader::nextIntArrray(int len, short bytes_per_int)
  {
    vector<int> result;
    COUNTER_LOOP(i, 0, len)
    {
      result.push_back(nextInt(bytes_per_int));
    }
    return result;
  }

  float BinaryStreamReader::nextFloat()
  {
    union
    {
      float result;
      uchar b[4];
    } u;

    u.b[3] = data_[pos_++];
    u.b[2] = data_[pos_++];
    u.b[1] = data_[pos_++];
    u.b[0] = data_[pos_++];

    return u.result;

  }

  std::vector<float> BinaryStreamReader::nextFloatArrray(int len)
  {
    std::vector<float> result;
    COUNTER_LOOP(i, 0, len)
      result.push_back(nextFloat());
    return result;
  }

} /* namespace gconverter */
